/** Definition of the SymbolTable class
 * @file
 * @author Jeremy Schultz
 */

#ifndef	__SYMBOLTABLE_H_
#define	__SYMBOLTABLE_H_

#include <iostream>
#include <assert.h>
#include <map>
#include <vector>
#include <iomanip>
#include "Word.h"

// Block 0 is used to store keywords
//  Thus do not count it as a user block
//  Max 10 user blocks = 11 Max Blocks
#define MAX_BLOCKS	11

using namespace std;

/** Symbol Table to hold Word objects
 * The Symbol table is used in different parts of the compiler.
 * It will give linear access time for finding a Symbol.
 */
class SymbolTable	{
	private:
		vector< map<string,Word> > blocks;	/**< vectors of blocks (symbol tables) */
		int offset[MAX_BLOCKS];

	public:
		/** Constructor.
		 */
		SymbolTable();

		/** Find a Word.
		 * Currently, not implemented.
		 * Scanner (assignmnet 1) does not need it.
		 * The definition may change later on.
		 * @param word	the string we are trying to find
		 * @return The found symbol (Word)
		 */
		Word* find(string word);

		/** Insert a symbol (Word).
		 * The Word will only be inserted if it is not in the table
		 *  already.
		 * @param word The Word object to be inserted
		 * @return	The Word inserted or the previously inserted word
		 */
		bool insert(Word* word);

		/** Search all blocks (entire symbol table).
		 * @param word The string to search for
		 * @return an iterator of block the Word was found in
		 */
		int search(string word);


		/** Is the word a keyword.
		 * @param word The string to see if it is a keyword
		 * @return True or False
		 */
		bool isKeyword(string word);
		

		/** Insert a list words.
		 * Create a Word from a string array and insert them.
		 * This is primarily used to insert the list of keywords.
		 * @param list	an array of strings
		 */
		void insert(const string* list);

		/** Create a new block
		 * Pushes a new block (symbol table) on the stack.
		 * Also inserts the Keywords into new block.
		 */
		bool newBlock();

		/** Remove a block
		 *  Pops a block (symbol table) on the stack.
		 */
		void destroyBlock();

		/** Level of current block.
		 * @return The Level of the current block
		 */
		int blockLevel();


		/** Next offset.
		 * Get the next offset in the current block
		 * @return The offset
		 */
		int nextOffset();

		/** Dump the table for debugging purposes.
		 * Will print a formated listing of the symbol table.
		 */
		void dumpTable();
};
#endif

